import {addClass, addListener, getData, isNumber, removeClass} from "./utils";

export default {
    show() {
        console.log('method', 'show');
        if (this.showing || this.isShown) {
            return this
        }
        if (!this.ready) {
            this.build()
            if (this.ready) this.show()
            return this
        }
        this.showing = true
        this.open()
        removeClass(this.viewer, 'viewer-hide')

        const {viewer} = this
        const shown = this.shown.bind(this)

        addClass(viewer, 'viewer-transition')
        viewer.initialOffsetWidth = viewer.offsetWidth
        addListener(viewer, 'transitionend', shown, {once: true})
        addClass(viewer, 'viewer-in')
        return this;
    },
    hide() {
        console.log('method', 'hide');
        if (this.hiding || !(this.isShown || this.showing)) {
            return this
        }
        this.hiding = true
        const {viewer} = this
        const hidden = this.hidden.bind(this)
        const hide = () => {
            setTimeout(() => {
                addListener(viewer, 'transitionend', hidden, {once: true})
                removeClass(viewer, 'viewer-in')
            }, 0)
        }

        if (this.viewed) {
            addListener(this.image, 'transitionend', hide, {once: true})
            this.zoomTo(0, false, false, false)
        } else {
            hide()
        }
        return this;
    },
    view() {
        console.log('method', 'view');
        if (!this.isShown) {
            return this.show()
        }
        const {element, canvas} = this
        this.index = 0
        const item = this.items[this.index]
        const img = item.querySelector('img')
        const image = document.createElement('img')
        image.src = getData(img, 'originalUrl')
        image.alt = img.getAttribute('alt')
        this.image = image
        addClass(image, 'viewer-invisible')
        addClass(canvas, 'viewer-loading')
        canvas.innerHTML = ''
        canvas.appendChild(image)

        this.renderList()

        addListener(image, 'load', this.load.bind(this), {once: true})

        if (this.timeout) clearTimeout(this.timeout)

        this.timeout = setTimeout(() => {
            removeClass(image, 'viewer-invisible')
            this.timeout = false
        }, 1000)

        return this;
    },
    zoom(ratio, hasTooltip = false, _originalEvent = null) {
        const {imageData} = this
        ratio = Number(ratio)
        if (ratio < 0) {
            ratio = 1 / (1 - ratio)
        } else {
            ratio = 1 + ratio
        }
        this.zoomTo((imageData.width * ratio) / imageData.naturalWidth, hasTooltip, _originalEvent)

        return this
    },
    zoomTo(ratio, hasTooltip = false, _originalEvent = false, _zoomable = false) {
        const {imageData} = this
        const {width, height, naturalWidth, naturalHeight} = imageData
        ratio = Math.max(0, ratio)

        if (isNumber(ratio) && this.viewed) {
            if (!_zoomable) {
                // 限制缩放最大最小比例
                ratio = Math.min(Math.max(ratio, 0.01), 100)
            }
            this.zooming = true
            const newWidth = naturalWidth * ratio
            const newHeight = naturalHeight * ratio
            const offsetWidth = newWidth - width
            const offsetHeight = newHeight - height

            imageData.left -= offsetWidth / 2
            imageData.top -= offsetHeight / 2

            imageData.width = newWidth
            imageData.height = newHeight
            imageData.ratio = ratio
            this.renderImage(() => {
                this.zooming = false
            })
        }

        return this
    },
    open() {
        const {body} = this
        addClass(body, 'viewer-open')
        body.style.paddingRight = `${this.scrollbarWidth + (parseFloat(this.initialBodyPaddingRight) || 0)}px`
    },
    close() {
        const {body} = this
        removeClass(body, 'viewer-open')
        body.style.paddingRight = this.initialBodyPaddingRight
    },
    shown() {
        console.log('method', 'shown')
        this.fulled = true
        this.isShown = true
        this.render()
        this.bind()
        this.showing = false
        if (this.ready && this.isShown) {
            this.view()
        }
    },
    hidden() {
        console.log('method', 'hidden')
        this.fulled = false
        this.viewed = false
        this.isShown = false
        this.close()
        this.unbind()
        addClass(this.viewer, 'viewer-hide')
        this.resetList()
        this.resetImage()
        this.hiding = false
    }
}
